/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 * ***************************************************************************/


#if !defined(AFX_PGLIMAGE_H__A94FFCAF_8F2D_4E00_A329_E92AD7C42789__INCLUDED_)
#define AFX_PGLIMAGE_H__A94FFCAF_8F2D_4E00_A329_E92AD7C42789__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <pgl/core/PGLObject.h>
#include <pgl/core/PGLArea2D.h>

/*! \brief Image object.

<h3>File format supported</h3>
  The available image formats are:
  - jpg
  - tiff
  - png
  - bmp

<h3>Loading images</h3>
  PGL provides 3 methods to load images (#Load methods): 
	- form a file by giving the file name, 
	- from ressource by giving the ressource ID,
	- from BITMAPINFO structure by giving the BITMAPINFO structure and the array of bytes.

  When loading the image, you can ask PGL to update the area object (see section below) with the dimensions of the bitmap.

<h3>Controlling the display of the image</h3>
	The object contains a CPGLArea2D member that determines the size and position of the bitmap. The area can accessed via 
	classical getters and setters (CPGLImage::GetArea, CPGLImage::SetArea, etc...)

<h3>Serialization</h3>
	The serialization depends on the type of loading:
	- by file, the file name is stored. So the user should make sure, the image is still in the path when loading the data.
	- by resource, the resource ID is stored. If passing data between programs, this ID should point to the same bitmap.
	- by BITMAPINFO, no implement yet.


  \todo Implement Bitmap in EPS and SVG
  \todo Serialization for BITMAPINFO images
  \ingroup PGLMiscChartGroup
*/
class PGLCORE_EXT_CLASS CPGLImage : public CPGLObject  
{
PGL_DECLARE_DYNCREATE(CPGLImage);
public:
	//! Image source type
	enum ESourceType
	{
		//! Not loaded, no source
		SourceTypeNone =		0,
		//! loaded from file
		SourceTypeFile =		1,
		//! Loaded from resource ID
		SourceTypeResource =	2,
		//! Loaded from BitmapInfo
		SourceTypeBITMAPINFO= 3
	};
public:
	//! \name Constructors
	//@{
	//! Default constructor...
	CPGLImage(LPCTSTR szFileName = NULL, bool bUpdateArea = true);
	//! Copy constructor
	CPGLImage(const CPGLImage& img)	{*this = img;};
	//! Assignement constructor
	CPGLImage& operator = (const CPGLImage& img);
	//! desctuctor
	virtual ~CPGLImage();
	//@}

	//! \name Image loading, unloading
	//@{
	/*! \brief Loading image from a file.

	The extension of szFileName determines the type of image. Accepted types of images are:
		- jpg 
		- png 
		- bmp 
		- tiff
		- emf
		- wmf

	\param szFileName Pointer to a null-terminated string that specifies the path name of the image file. 
	\param bUpdateArea Boolean to specify wheter the area object should be updated: the area is set to width and height of the bitmap.
	\return true if loading succesfull.

	- Note that a call to load function, will always unload the previous bitmap (if any).
	- Raster and metafile image don't behave the same way when streched...
	*/
	bool Load(LPCTSTR szFileName, bool bUpdateArea = true);

	/*! \brief Loading image from ressource

	\param IDResource ressource ID
	\param hInstance Handle to an instance of a module whose executable file contains a bitmap resource. If NULL, AfxGetInstanceHandle() is used.
	\param bUpdateArea Boolean to specify wheter the area object should be updated: the area is set to width and height of the bitmap.	
	\return true if loading succesfull.
	*/
	bool Load(DWORD IDResource, HINSTANCE hInstance = NULL, bool bUpdateArea = true);

	/*! \brief Loading image from BITMAPINFO

	\param gdiBitmapInfo  Pointer to a GDI BITMAPINFO structure. This structure defines several bitmap attributes, such as size and pixel format. The BITMAPINFO structure is defined in Wingdi.h.
	\param gdiBitmapData, Pointer to an array of bytes that contains the pixel data. 
	\param bUpdateArea Boolean to specify wheter the area object should be updated: the area is set to width and height of the bitmap.	
	\return true if loading succesfull.
	*/
	bool Load( const BITMAPINFO* gdiBitmapInfo, VOID* gdiBitmapData, bool bUpdateArea = true);

	/*! Unload image

	\return true if unloading succesfull.
	*/
	bool UnLoad();
	//! returns current source type
	ESourceType GetSourceType() const		{	return m_eSourceType;};
	//@}
	
	//! \name Area
	//@{
	//! Sets area of bitmap
	void SetArea(const CPGLArea2D& area)	{	m_area =area;};
	//! returns reference to bitmap area
	CPGLArea2D& GetArea()					{	return m_area;};
	//! returns reference to bitmap area, const
	const CPGLArea2D& GetArea() const		{	return m_area;};
	//@}

	//! \name Image dimensions (in pixels)
	//@{
	//! returns original image width in pixels
	int GetWidth() const;
	//! returns original image height in pixels
	int GetHeight() const;
	//! returns bitmap pointer
	Gdiplus::Bitmap* GetGDIpBitmap() {	return m_pBitmap;};
	//! return HBITMAP
	HBITMAP GetHBITMAP();
	//@}

	//! \name Active portion
	//@{
	//! returns active portion of bitmap
//	const CPGLRectU& GetActiveRect() const				{	return m_rActiveRect;};
/*	/*! \brief Sets active portion of bitmap
	
	  If the portion given by the user is greater than the bitmap dimensions, it is rescaled.
		\return true if succesful, false otherwize		
	*/
//	bool SetActiveRect(const CPGLRectU& rActiveRect);
	//@}

	
	//! \name Virutal plotting functions
	//@{
	//! Main plot function
	virtual void PlotGfx(gfxinterface::CGfxInterface& gfx);
	//! Gets the extent of the bitmap
	virtual void GetUnionExtent(gfxinterface::CGfxInterface& gfx, CPGLRectD& rExtent);
	//! Updates the extent of the bitmap (see Area section)
	virtual void UpdateExtent(gfxinterface::CGfxInterface& gfx);
	//@}
	
	//! \name Serialization and debugging
	//@{
	//! Serialization
	void SerializeXML( CPGLArchive& ar);
	//! Converts ESourceType enum to string
	static LPCTSTR SourceTypeToString(ESourceType eSourceType);
	//! Converts szSourceType to ESourceType
	static ESourceType StringToSourceType(LPCTSTR szSourceType);
	#ifdef _DEBUG
		//! MFC Dump
	    virtual void Dump( CDumpContext& dc ) const;
		//! MFC AssertValid
	    virtual void AssertValid() const;    // Override
	#endif
	//@}

protected:
	//! \name Attributes
	//@{
	//! File Name.
	CString m_sFileName;
	//! Ressource ID
	DWORD m_dwIDResource;
	//! area
	CPGLArea2D m_area;
	//! Bitmap pointer
	Gdiplus::Bitmap* m_pBitmap;
	//! source type
	ESourceType m_eSourceType;
	//! Active portion of bitmap
//	CPGLRectU m_rActiveRect;
	//@}
};

PGL_DECLARE_SMARTPTR( CPGLImage );

/*! \example bitmap.cpp
 Loading and displaying images.

\image html bitmap.png "A streched and non-streched bitmap"
*/

#endif // !defined(AFX_PGLIMAGE_H__A94FFCAF_8F2D_4E00_A329_E92AD7C42789__INCLUDED_)
